package com.xsy.glsurfaceview

import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.opengl.GLES30
import android.opengl.GLSurfaceView
import android.opengl.Matrix
import android.util.AttributeSet
import android.util.Log
import com.xsy.glsurfaceview.utils.ShaderUtils
import javax.microedition.khronos.egl.EGLConfig
import javax.microedition.khronos.opengles.GL10


class MyGLSurfaceViewBlur(context: Context, attributeSet: AttributeSet) :
    GLSurfaceView(context, attributeSet) {
    private var render: MyGLRenderBlur

    init {
        setEGLContextClientVersion(3)
        val fragmentShaderCode = ShaderUtils.readFileFromAssets(context, TextureRenderBlur.fragment_file_path)
        val vertexShaderCode = ShaderUtils.readFileFromAssets(context, TextureRenderBlur.vertex_file_path)
        Log.d("MyGLSurfaceView", "fragment shader code: $fragmentShaderCode")
        Log.d("MyGLSurfaceView", "vertex shader code: $vertexShaderCode")
        render = MyGLRenderBlur(context, vertexShaderCode, fragmentShaderCode)
        setRenderer(render)
        render
    }

    fun onDestroy() {
        render.onDestroy()
    }
}

class MyGLRenderBlur(
    private val context: Context,
    private val vertexShaderCode: String,
    private val fragmentShaderCode: String
) :
    GLSurfaceView.Renderer {
    private lateinit var textureRender: TextureRenderBlur
    private var bitmap: Bitmap
    private var mIWidth: Int = 0
    private var mIHeight: Int = 0
    private var mSurfaceViewWidth = 0
    private var mSurfaceViewHeight = 0

    private var mMM: FloatArray = FloatArray(16)
    private var mMV: FloatArray = FloatArray(16)
    private var mProjM: FloatArray = FloatArray(16)
    private var mViewM: FloatArray = FloatArray(16)
    private var mMVP: FloatArray = FloatArray(16)

    init {
        bitmap = loadImage()
        mIWidth = bitmap.width
        mIHeight = bitmap.height
        Matrix.setIdentityM(mMM, 0)
        //还原坐标位置
        mMM[0]= -1.0f
    }

    private fun loadImage(): Bitmap {
        val options = BitmapFactory.Options()
        options.inScaled = false
        return BitmapFactory.decodeResource(context.resources, R.drawable.bgirl, options)
    }

    override fun onSurfaceCreated(gl: GL10?, config: EGLConfig?) {
        GLES30.glClearColor(1.0f, 0.0f, 0.0f, 1.0f)
        textureRender = TextureRenderBlur(bitmap, vertexShaderCode, fragmentShaderCode)
    }

    override fun onSurfaceChanged(gl: GL10?, width: Int, height: Int) {
        GLES30.glViewport(0, 0, width, height)
        Log.d("MyGLSurfaceView", "width: $width")
        Log.d("MyGLSurfaceView", "height: $height")
        mSurfaceViewWidth = width
        mSurfaceViewHeight = height
        //计算正交投影矩阵，修正变形
        calculateViewport2()
    }

    private fun calculateViewport2() {
        val imageRatio = mIWidth / mIHeight.toFloat()
        val surfaceRatio = mSurfaceViewWidth / mSurfaceViewHeight.toFloat()
        if (imageRatio > surfaceRatio) {
            val tb = imageRatio / surfaceRatio
            Matrix.orthoM(mProjM, 0, -1.0f, 1.0f, -tb, tb, -1.0f, 1.0f)
        } else if (imageRatio < surfaceRatio) {
            val lr = surfaceRatio / imageRatio
            Matrix.orthoM(mProjM, 0, -lr, lr, -1.0f, 1.0f, -1.0f, 1.0f)
        } else {
            Matrix.orthoM(mProjM, 0, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f)
        }
        Matrix.setLookAtM(
            mViewM, 0,
            0.0f, 0.0f, -1.0f,
            0.0f, 0.0f, 0.0f,
            0.0f, 1.0f, 0.0f
        )
    }


    override fun onDrawFrame(gl: GL10?) {
        GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT)
        Matrix.multiplyMM(mMV, 0, mViewM, 0, mMM, 0)
        Matrix.multiplyMM(
            mMVP, 0,
            mProjM, 0,
            mMV, 0
        )
        textureRender.draw(mMVP)
    }

    fun onDestroy() {
        textureRender.onDestroy()
    }

}